Fix netfront receive path for auto_translate_physmap mode.
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 23 Feb 2006 14:22:12 +0000 (15:22 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 23 Feb 2006 14:22:12 +0000 (15:22 +0100)
Signed-off-by: Steven Smith <sos22@cam.ac.uk>
Signed-off-by: Keir Fraser <keir@xensource.com>
linux-2.6-xen-sparse/drivers/xen/core/gnttab.c
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
linux-2.6-xen-sparse/include/xen/gnttab.h

index e02977d4b86ec23cbebb1d3803066a650ba8f46e..b9099b0ec131f6a57540a248617c4e0f1f0609da 100644 (file)
@@ -222,25 +222,22 @@ gnttab_end_foreign_access(grant_ref_t ref, int readonly, unsigned long page)
 }
 
 int
-gnttab_grant_foreign_transfer(domid_t domid)
+gnttab_grant_foreign_transfer(domid_t domid, unsigned long pfn)
 {
        int ref;
 
        if (unlikely((ref = get_free_entry()) == -1))
                return -ENOSPC;
-
-       shared[ref].frame = 0;
-       shared[ref].domid = domid;
-       wmb();
-       shared[ref].flags = GTF_accept_transfer;
+       gnttab_grant_foreign_transfer_ref(ref, domid, pfn);
 
        return ref;
 }
 
 void
-gnttab_grant_foreign_transfer_ref(grant_ref_t ref, domid_t domid)
+gnttab_grant_foreign_transfer_ref(grant_ref_t ref, domid_t domid,
+                                 unsigned long pfn)
 {
-       shared[ref].frame = 0;
+       shared[ref].frame = pfn;
        shared[ref].domid = domid;
        wmb();
        shared[ref].flags = GTF_accept_transfer;
index b1ed9453bfb76755699df35217b747864705ad2c..10165268c6cd1bb7365e8b0dc02e904fb6d773dc 100644 (file)
@@ -587,25 +587,23 @@ static void network_alloc_rx_buffers(struct net_device *dev)
                BUG_ON((signed short)ref < 0);
                np->grant_rx_ref[id] = ref;
                gnttab_grant_foreign_transfer_ref(ref,
-                                                 np->xbdev->otherend_id);
+                                                 np->xbdev->otherend_id,
+                                                 __pa(skb->head) >> PAGE_SHIFT);
                RING_GET_REQUEST(&np->rx, req_prod + i)->gref = ref;
                rx_pfn_array[i] = virt_to_mfn(skb->head);
 
-               /* Remove this page from map before passing back to Xen. */
-               set_phys_to_machine(__pa(skb->head) >> PAGE_SHIFT,
-                                   INVALID_P2M_ENTRY);
-
-               MULTI_update_va_mapping(rx_mcl+i, (unsigned long)skb->head,
-                                       __pte(0), 0);
+               if (!xen_feature(XENFEAT_auto_translated_physmap)) {
+                       /* Remove this page before passing back to Xen. */
+                       set_phys_to_machine(__pa(skb->head) >> PAGE_SHIFT,
+                                           INVALID_P2M_ENTRY);
+                       MULTI_update_va_mapping(rx_mcl+i,
+                                               (unsigned long)skb->head,
+                                               __pte(0), 0);
+               }
        }
 
-       /* After all PTEs have been zapped we blow away stale TLB entries. */
-       rx_mcl[i-1].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL;
-
-       /* Give away a batch of pages. */
-       rx_mcl[i].op = __HYPERVISOR_memory_op;
-       rx_mcl[i].args[0] = XENMEM_decrease_reservation;
-       rx_mcl[i].args[1] = (unsigned long)&reservation;
+       /* Tell the ballon driver what is going on. */
+       balloon_update_driver_allowance(i);
 
        reservation.extent_start = rx_pfn_array;
        reservation.nr_extents   = i;
@@ -613,15 +611,27 @@ static void network_alloc_rx_buffers(struct net_device *dev)
        reservation.address_bits = 0;
        reservation.domid        = DOMID_SELF;
 
-       /* Tell the ballon driver what is going on. */
-       balloon_update_driver_allowance(i);
+       if (!xen_feature(XENFEAT_auto_translated_physmap)) {
+               /* After all PTEs have been zapped, flush the TLB. */
+               rx_mcl[i-1].args[MULTI_UVMFLAGS_INDEX] =
+                       UVMF_TLB_FLUSH|UVMF_ALL;
+
+               /* Give away a batch of pages. */
+               rx_mcl[i].op = __HYPERVISOR_memory_op;
+               rx_mcl[i].args[0] = XENMEM_decrease_reservation;
+               rx_mcl[i].args[1] = (unsigned long)&reservation;
 
-       /* Zap PTEs and give away pages in one big multicall. */
-       (void)HYPERVISOR_multicall(rx_mcl, i+1);
+               /* Zap PTEs and give away pages in one big multicall. */
+               (void)HYPERVISOR_multicall(rx_mcl, i+1);
 
-       /* Check return status of HYPERVISOR_memory_op(). */
-       if (unlikely(rx_mcl[i].result != i))
-               panic("Unable to reduce memory reservation\n");
+               /* Check return status of HYPERVISOR_memory_op(). */
+               if (unlikely(rx_mcl[i].result != i))
+                       panic("Unable to reduce memory reservation\n");
+       } else {
+               if (HYPERVISOR_memory_op(XENMEM_decrease_reservation,
+                                        &reservation) != i)
+                       panic("Unable to reduce memory reservation\n");
+       }
 
        /* Above is a suitable barrier to ensure backend will see requests. */
        np->rx.req_prod_pvt = req_prod + i;
@@ -802,17 +812,19 @@ static int netif_poll(struct net_device *dev, int *pbudget)
                np->stats.rx_packets++;
                np->stats.rx_bytes += rx->status;
 
-               /* Remap the page. */
-               MULTI_update_va_mapping(mcl, (unsigned long)skb->head,
-                                       pfn_pte_ma(mfn, PAGE_KERNEL), 0);
-               mcl++;
                if (!xen_feature(XENFEAT_auto_translated_physmap)) {
+                       /* Remap the page. */
+                       MULTI_update_va_mapping(mcl, (unsigned long)skb->head,
+                                               pfn_pte_ma(mfn, PAGE_KERNEL),
+                                               0);
+                       mcl++;
                        mmu->ptr = ((maddr_t)mfn << PAGE_SHIFT)
                                | MMU_MACHPHYS_UPDATE;
                        mmu->val = __pa(skb->head) >> PAGE_SHIFT;
                        mmu++;
 
-                       set_phys_to_machine(__pa(skb->head) >> PAGE_SHIFT, mfn);
+                       set_phys_to_machine(__pa(skb->head) >> PAGE_SHIFT,
+                                           mfn);
                }
 
                __skb_queue_tail(&rxq, skb);
@@ -1003,7 +1015,8 @@ static void network_connect(struct net_device *dev)
                if ((unsigned long)np->rx_skbs[i] < __PAGE_OFFSET)
                        continue;
                gnttab_grant_foreign_transfer_ref(
-                       np->grant_rx_ref[i], np->xbdev->otherend_id);
+                       np->grant_rx_ref[i], np->xbdev->otherend_id,
+                       __pa(np->rx_skbs[i]->data) >> PAGE_SHIFT);
                RING_GET_REQUEST(&np->rx, requeue_idx)->gref =
                        np->grant_rx_ref[i];
                RING_GET_REQUEST(&np->rx, requeue_idx)->id = i;
index 3dbdbfb1e93833bd5bde3ccf28679a759b94c1d5..58aeb492b0b9b6e3978cfc1e2bc366aadc1fc133 100644 (file)
@@ -71,7 +71,7 @@ int gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly);
 void gnttab_end_foreign_access(grant_ref_t ref, int readonly,
                               unsigned long page);
 
-int gnttab_grant_foreign_transfer(domid_t domid);
+int gnttab_grant_foreign_transfer(domid_t domid, unsigned long pfn);
 
 unsigned long gnttab_end_foreign_transfer_ref(grant_ref_t ref);
 unsigned long gnttab_end_foreign_transfer(grant_ref_t ref);
@@ -98,7 +98,8 @@ void gnttab_request_free_callback(struct gnttab_free_callback *callback,
 void gnttab_grant_foreign_access_ref(grant_ref_t ref, domid_t domid,
                                     unsigned long frame, int readonly);
 
-void gnttab_grant_foreign_transfer_ref(grant_ref_t, domid_t domid);
+void gnttab_grant_foreign_transfer_ref(grant_ref_t, domid_t domid,
+                                      unsigned long pfn);
 
 #ifdef __ia64__
 #define gnttab_map_vaddr(map) __va(map.dev_bus_addr)